package cn.hl.user.interceptor;

import cn.hl.basic.jwt.JwtUtils;
import cn.hl.basic.jwt.LoginData;
import cn.hl.basic.jwt.Payload;
import cn.hl.basic.jwt.RsaUtils;
import cn.hl.org.mapper.EmployeeMapper;
import cn.hl.system.annotation.PreAuthorize;
import cn.hl.user.domain.Logininfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.security.PublicKey;
import java.util.List;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 有没有登录过
        String token = request.getHeader("token");
        // 如果token不为空：再去获取登录信息
        if (token != null) {
                Logininfo logininfo = null;
                try {
                    // 获取公钥
                    PublicKey publicKey = RsaUtils.getPublicKey(JwtUtils.class.getClassLoader().getResource("auth_rsa.pub").getFile());
                    // 解密之后获取载荷数据
                    Payload<LoginData> payload = JwtUtils.getInfoFromToken(token, publicKey, LoginData.class);
                    // 从载荷数据中获取loginingo对象
                    logininfo = payload.getLoginData().getLogininfo();
                } catch (Exception e) {
                    // jwt登录超时响应给前端
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().println(" {\"success\":false,\"message\":\"timeout\"}");
                    return false;
                }
                /*// 有登录信息，放行并刷新登录时间
                redisTemplate.opsForValue().set(token,obj,30, TimeUnit.MINUTES);
                // 获取登录成功对象logininfo
                Logininfo logininfo = (Logininfo)obj;*/
                // 根据type判断是否为前台用户user，如果是直接放行
                if (logininfo.getType().intValue() == 1) {
                    return true;
                }
                // 校验权限
                HandlerMethod handlerMethod = (HandlerMethod)handler;
                // 获取当前请求接口是否有权限信息，自定义注解
                PreAuthorize preAuthorize = handlerMethod.getMethodAnnotation(PreAuthorize.class);
                // 判断preAuthorize是否为空，为空说明没有自定义注解，是公共资源，直接放行
                if (preAuthorize == null) {
                    return true;
                } else {
                    // 不为空，说明有自定义注解，需要校验权限，获取注解上的sn
                    String sn = preAuthorize.sn();
                    // 查询出当前登录人的所有权限：t_permission的sn
                    List<String> ownPermissions = employeeMapper.findPermissionSnByLogininfoId(logininfo.getId());
                    // 如果集合ownPermissions中包含了sn，说明有权限访问，放行
                    if (ownPermissions.contains(sn)) {
                        return true;
                    }
                    // 如果不包含，响应给前端没有权限访问，去联系管理员
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType("application/json;charset=UTF-8");
                    PrintWriter writer = response.getWriter();
                    writer.println("{\"success\":false,\"message\":\"noPermission\"}");
                    writer.close();
                    return false;
                }
            }
        // 如果token为空,没有登录过,响应给前端
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println("{\"success\":false,\"message\":\"noLogin\"}");
        return false;
    }
}
